﻿using Consul;
using GWB.Core.Common.Entity;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GWB.System.Api.Extensions
{
    public static class Consul
    {
        public static IApplicationBuilder UseConsul(this IApplicationBuilder app, IConfiguration configuration, IHostApplicationLifetime lifetime)
        {

            #region 服务注册

            var client = new ConsulClient(options =>
            {
                options.Address = new Uri(configuration["Consul:Address"]); // Consul客户端地址
            });
            var registration = new AgentServiceRegistration
            {
                ID = Guid.NewGuid().ToString(), // 唯一Id
                Name = configuration["Consul:Name"], // 服务名
                Address = configuration["Consul:Ip"], // 服务绑定IP
                Port = Convert.ToInt32(configuration["Consul:Port"]), // 服务绑定端口
                Check = new AgentServiceCheck
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), // 服务启动多久后注册
                    Interval = TimeSpan.FromSeconds(10), // 健康检查时间间隔
                    HTTP = $"http://{configuration["Consul:Ip"]}:{configuration["Consul:Port"]}{configuration["Consul:HealthCheck"]}", // 健康检查地址
                    Timeout = TimeSpan.FromSeconds(5) // 超时时间
                }
            };
            // 注册服务
            client.Agent.ServiceRegister(registration).Wait();

            // 应用程序终止时，取消服务注册
            lifetime.ApplicationStopping.Register(() =>
            {
                client.Agent.ServiceDeregister(registration.ID).Wait();
            });

            #endregion

            #region 服务发现
            var dictionary = client.Agent.Services().Result.Response;
            var list = new List<ServiceInfo>();
            foreach (var item in dictionary)
            {
                AgentService agentService = item.Value;
               
                if (agentService.TaggedAddresses != null && agentService.TaggedAddresses.Count >= 2)
                {
                    list.Add(new ServiceInfo()
                    {
                        Address = agentService.Address,
                        Port = agentService.Port,
                        Service = agentService.Service
                    });
                }
            }
            CurrentConsul.ServiceInfos = list;
            #endregion

            return app;
        }
    }
}
